using System.Diagnostics;
using ConfigurationSettings;
using CustomControls;
using FileTracker.Forms;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ServiceLocator;

//Lambda to avoid unnecessary parameter passing
//button.Click += (sender, args) => SaveCurrentDocument();

namespace FileTracker
{
    public partial class MainView : ViewBase
    {
	    private IApplicationSettings _localSettings;

        /// <summary>
        /// Delegate for the mapping of Methods to key presses.
        /// </summary>
        private delegate void KeyMethod();

        /// <summary>
        /// Dictionary Entries for all the key mappings.
        /// </summary>
        readonly Dictionary<Keys, KeyMethod> _localKeyMapping;

        public MainController Controller
        {
            private get { return (MainController)_controller; }
            set { _controller = value; }
        }

        #region ** Constructors, Destructors, and Closing events **

        /// <summary>
        /// Standard constructor.
        /// </summary>
        public MainView()
        {
	        _localKeyMapping = new Dictionary<Keys, KeyMethod>();
	        _localSettings = Locator.Resolve<IApplicationSettings>();

	        InitializeComponent();
        }

	    /// <summary>
        /// Sets the location and other settings when the main form loads.
        /// </summary>
        /// <param name="argSender">The object raising this event. Unused.</param>
        /// <param name="argEvtArgs">The event arguments object. Unused.</param>
        private void FormMainLoad(object argSender, EventArgs argEvtArgs)
        {
            {
                //Set the mainForm settings
                //Don't put the window size in SetConfiguration because they don't get
                //  set in the Preferences window
				Size = _localSettings.MainWindowSize;
				Location = _localSettings.MainWindowLocation;
				splitContainerMain.SplitterDistance = _localSettings.MainSplitterDistance;

                //This goes first to set the Source and Dest views
                fileListViewLeft_Enter(null, null);

                //Setup the environment from the config file
                SetConfiguration();

                fileListViewLeft.SynchPathEvent += Controller.SynchPathEvent;
                fileListViewRight.SynchPathEvent += Controller.SynchPathEvent;

            }
        }

        /// <summary>
        /// Saves the location and other settings when the form closes.
        /// </summary>
        /// <param name="argSender">Unused.</param>
        /// <param name="argEvtArgs">Unused.</param>
        private void FormMainFormClosing(object argSender, FormClosingEventArgs argEvtArgs)
        {
            {
				_localSettings.MainSplitterDistance = splitContainerMain.SplitterDistance;

				_localSettings.MainWindowLocation = Location;
				_localSettings.MainWindowSize = Size;

				_localSettings.Save();

            }
        }

        private void MainFormFormClosed(object argSender, FormClosedEventArgs argEventArgs)
        {
            {
                Controller.OnExit();
            }
        }

        #endregion

        #region ** FileTrackerConfiguration Methods **

        /// <summary>
        /// Sets the various configurable parameters of the FileSystemListView objects as well as loading other configuration parameters.
        /// </summary>
        private void SetConfiguration()
        {
            {
                try
                {
                    Controller.SetConfiguration();
                }
                catch (Exception configurationEx)
                {
                    MessageBox.Show(string.Format("Error in SetConfiguration: {0}", configurationEx.Message));
                }
            }
        }

        #endregion

        #region ** Favorites Methods **

        /// <summary>
        /// Opens the "Add MenuItemFavoriteLeft" dialog box.
        /// </summary>
        /// <param name="argSender">The object raising this event. Unused.</param>
        /// <param name="argEvtArgs">The event arguments object. Unused.</param>
        private void ToolStripMenuItemAddFavoriteClick(object argSender, EventArgs argEvtArgs)
        {
            {
                Controller.AddFavorite();
            }
        }

        /// <summary>
        /// Opens the "Edit Favorites" dialog box.
        /// </summary>
        /// <param name="argSender">The object raising this event. Unused.</param>
        /// <param name="argEvtArgs">The event arguments object. Unused.</param>
        private void ToolStripMenuItemEditFavoritesClick(object argSender, EventArgs argEvtArgs)
        {
            {
                Controller.EditFavorite();
            }
        }

        #endregion

        #region ** OpenWith Methods **


        /// <summary>
        /// Add programs to the "Open With" sub-menu.
        /// </summary>
        /// <param name="argSender">The object raising this event. Unused.</param>
        /// <param name="argEvtArgs">The event arguments object. Unused.</param>
        private void ToolStripMenuItemAddOpenWithClick(object argSender, EventArgs argEvtArgs)
        {
            {
                Controller.AddOpenWith();
            }
        }

        /// <summary>
        /// Edit the list of programs offered in the "Open With" sub-menu.
        /// </summary>
        /// <param name="argSender">The object raising this event. Unused.</param>
        /// <param name="argEvtArgs">The event arguments object. Unused.</param>
        private void ToolStripMenuItemEditOpenWithClick(object argSender, EventArgs argEvtArgs)
        {
            {
                Controller.EditOpenWith();
            }
        }

        #endregion

        #region ** Toolstrip Button Methods **

        /// <summary>
        /// Stubs out the RefreshFileList method.
        /// </summary>
        /// <param name="argSender">The object raising this event. Unused.</param>
        /// <param name="argEvtArgs">The event arguments object. Unused.</param>
        private void ToolStripButtonRefreshClick(object argSender, EventArgs argEvtArgs)
        {
            {
                Controller.RefreshPath();
            }
        }

        /// <summary>
        /// Stubs out the CopyItem method.
        /// </summary>
        /// <param name="argSender">The object raising this event. Unused.</param>
        /// <param name="argEvtArgs">The event arguments object. Unused.</param>
        private void ToolStripButtonCopyClick(object argSender, EventArgs argEvtArgs)
        {
            {
                Controller.Copy();
            }
        }

        /// <summary>
        /// Stubs out the MoveItems method.
        /// </summary>
        /// <param name="argSender">The object raising this event. Unused.</param>
        /// <param name="argEvtArgs">The event arguments object. Unused.</param>
        private void ToolStripButtonMoveClick(object argSender, EventArgs argEvtArgs)
        {
            {
                Controller.MoveItem();
            }
        }

        /// <summary>
        /// Stubs out the MakeDir method.
        /// </summary>
        /// <param name="argSender">The object raising this event. Unused.</param>
        /// <param name="argEvtArgs">The event arguments object. Unused.</param>
        private void ToolStripButtonMakeDirClick(object argSender, EventArgs argEvtArgs)
        {
            {
                Controller.MakeDir();
            }
        }

        /// <summary>
        /// Stubs out the DeleteItem method.
        /// </summary>
        /// <param name="argSender">The object raising this event. Unused.</param>
        /// <param name="argEvtArgs">The event arguments object. Unused.</param>
        private void ToolStripButtonDeleteClick(object argSender, EventArgs argEvtArgs)
        {
            {
                Controller.DeleteItems();
            }
        }

        /// <summary>
        /// Copies each directory's content into the other directory.
        /// </summary>
        /// <param name="argSender">The object raising the event. Unused.</param>
        /// <param name="argEvtArgs">The event agruments object. Unused.</param>
        private void ToolStripButtonSynchDirClick(object argSender, EventArgs argEvtArgs)
        {
            {
                Controller.SyncDirs();
            }
        }

        /// <summary>
        /// Updates "Modified Date" on the selected files.
        /// </summary>
        /// <param name="argSender">Unused</param>
        /// <param name="argEventArgs">Unused</param>
        private void ToolStripButtonTouchClick(object argSender, EventArgs argEventArgs)
        {
            {
                Controller.TouchItems();
            }
        }

        #endregion

        #region ** Menuitem Methods **

        /// <summary>
        /// Executed when the user clicks the "Exit" menu item.
        /// </summary>
        /// <param name="argSender">The object raising this event. Unused.</param>
        /// <param name="argEventArgs">The event arguments object. Unused.</param>
        private void ToolStripMenuItemExitClick(object argSender, EventArgs argEventArgs)
        {
            {
                Close();
            }
        }

        /// <summary>
        /// Opens the About box
        /// </summary>
        /// <param name="argSender">Unused</param>
        /// <param name="argEventArgs">Unused</param>
        private void ToolStripMenuItemAboutClick(object argSender, EventArgs argEventArgs)
        {
            {
                using (AboutBoxFileTracker aboutBox = new AboutBoxFileTracker())
                {
                    aboutBox.ShowDialog();
                }
            }
        }

        /// <summary>
        /// For internal use only.
        /// </summary>
        /// <param name="argSender">Unused</param>
        /// <param name="argEventArgs">Unused</param>
        private void ToolStripMenuItemInfoClick(object argSender, EventArgs argEventArgs)
        {
            {
                //MessageBox.Show("Splitter position: " + splitterMain.Left.ToString() );
                //MessageBox.Show("Main Window Length: " + this.Length.ToString());
                //MessageBox.Show("Name column: " + fileSystemListViewLeft.Columns[0].Width.ToString());
                //MessageBox.Show("Length column: " + fileSystemListViewLeft.Columns[1].Width.ToString());
                //MessageBox.Show("Date column: " + fileSystemListViewLeft.Columns[2].Width.ToString());
            }
        }

        /// <summary>
        /// Opens the "Preferences" window.
        /// </summary>
        /// <param name="argSender">Unused</param>
        /// <param name="argEventArgs">Unused</param>
        private void ToolStripMenuItemPreferencesClick(object argSender, EventArgs argEventArgs)
        {
            {

                Controller.SetPreferences();
            }
        }

        #endregion

        #region ** Event Handlers **

        /// <summary>
        /// Executed when the user presses a key on the keyboard.
        /// </summary>
        /// <param name="argSender">The object raising this event. Unused.</param>
        /// <param name="argEventArgs">The event arguments object containing data regarding the key that was pressed.</param>        
        private void FormMainKeyDown(object argSender, KeyEventArgs argEventArgs)
        {
            {
               bool keyResult = Controller.KeyDown(argEventArgs.KeyCode);

               argEventArgs.SuppressKeyPress = keyResult;
               argEventArgs.Handled = keyResult;
            }
        }

        /// <summary>
        /// Executed when Windows has a message. Used to trap the Device Changed message and rescan the drives on the computer.
        /// </summary>
        /// <param name="argWndMessage">The message recieved.</param>
        protected override void WndProc(ref Message argWndMessage)
        {
	        base.WndProc(ref argWndMessage);
	        //If a device was inserted refresh the drives and favorites
	        //I don't need to keep such a close eye on what was added and where,
	        //just do a scan and pickup what's here now.
	        if (argWndMessage.Msg == (int) WindowsMessages.WM_DEVICECHANGE)
	        {
		        //TODO: 018 - Add code to poll devices and find WindowsMedia Devices
		        Controller.LoadFavorites();
	        }
        }

	    /// <summary>
        /// Activate the form and control if the user tries to drag something over the controls (in preperation for the Drop event).
        /// </summary>
        /// <param name="argSender">Unused.</param>
        /// <param name="argEventArgs">unused.</param>
        //TODO: 010 - Implement Drag/Drop in FileListView control
        private void FileSystemListViewDragEnter(object argSender, DragEventArgs argEventArgs)
        {
            {
                //Bring form to the front
                Activate();
                BringToFront();
            }
        }

        ///// <summary>
        ///// Refresh the FSLV after the drop action.
        ///// </summary>
        ///// <param name="argSender">Unused.</param>
        ///// <param name="argEventArgs">Unused.</param>
        //private void FileSystemListViewDragDrop(object argSender, DragEventArgs argEventArgs)
        //{
        //    // HTP fileSystemListViewLeft.RefreshPath();
        //    fileSystemListViewRight.RefreshPath();
        //    fileListViewLeft.RefreshPath();
        //}

        #endregion


        private void FilterToolStripMenuItemClick(object argSender, EventArgs argEvtArgs)
        {
            {
                Controller.EnableFilter(filterToolStripMenuItem.Checked);
            }
        }

        private void ButtonRenameClick(object argSender, EventArgs argEventArgs)
        {
            {
                Controller.RenameItems();
            }
        }

        private void ButtonModifyDateClick(object argSender, EventArgs argEventArgs)
        {
            {
                Controller.ModifyDate();
            }
        }

        private void fileListViewLeft_Enter(object argSender, EventArgs argEventArgs)
        {
            Controller.Model.SourceListView = fileListViewLeft;
            Controller.Model.DestListView = fileListViewRight;
        }

        private void fileListViewRight_Enter(object argSender, EventArgs argEventArgs)
        {
            Controller.Model.SourceListView = fileListViewRight;
            Controller.Model.DestListView = fileListViewLeft;
        }

    }
}